#include "Room.h"

#include "Tile.h"
#include "ObjectManager.h"
#include "Animation.h"
#include "GamePlayState.h"

// Enemies
#include "SwarmBot.h"
#include "TurretBot.h"
#include "TankBot.h"
#include "SapperBot.h"
#include "BackstabBot.h"
#include "RepairBot.h"

#include "DestroyEntityMessage.h"
#include "MessageSystem.h"

Room::Room(int difficult, int room) : Openings(0), spawned(false)
{
	difficulty = difficult;
	roomNumber = room;
	tileCount = 0;
}

Room::~Room(void)
{
	DestroyEntityMessage* msg;

	for(unsigned int i = 0; i < tileSet.size(); ++i)
	{
		tileSet[i]->Release();
		msg = new DestroyEntityMessage(tileSet[i]);
		MessageSystem::GetInstance()->SendMsg(msg);
		msg = nullptr;
		//delete tileSet[i];
	}
	tileSet.clear();

	for(unsigned int i = 0; i < enemySet.size(); ++i)
	{
		enemySet[i]->Release();
		msg = new DestroyEntityMessage(enemySet[i]);
		MessageSystem::GetInstance()->SendMsg(msg);
		msg = nullptr;
		//delete enemySet[i];
	}
	enemySet.clear();
}

void Room::AddTile(int tileType, int x, int y, int width, int height, const char* image, int left, int top, int right, int bottom)
{
	Tile* T = new Tile(tileType, x, y, width, height, image, roomNumber, left, top, right, bottom);

	tileSet.push_back(T);

	tileCount++;
}

void Room::AddTile(Tile* T)
{
	tileSet.push_back(T);
	T->AddRef();
	tileCount++;
}

void Room::AddEnemy(Enemy* e)
{
	enemySet.push_back(e);
	ObjectManager::GetInstance()->AddObject(e);
	spawned = true;
}

void Room::AddEnemy(int ER)
{
	spawned = true;

	// load animations
	Animation* tmp2 = new Animation;
	tmp2->LoadAnimationFromFile("TankMove.xml");
	int idT = AnimationSystem::GetInstance()->AddAnimation(tmp2);
	Animation* tmp3 = new Animation;
	tmp3->LoadAnimationFromFile("StabMove.xml");
	int idS = AnimationSystem::GetInstance()->AddAnimation(tmp3);
	Animation* tmp4 = new Animation;
	tmp4->LoadAnimationFromFile("repairBot.xml");
	int idH = AnimationSystem::GetInstance()->AddAnimation(tmp4);

	// Selects Enemy
	float spawnTimer = 25.0f;
	int enemyCount = 0;
	Enemy* enemy = nullptr;
	//difficulty = 0;
	while(difficulty > 0)
	{
		for(int i = 0; i < tileCount; ++i)
		{
			enemy = nullptr;
			if(tileSet[i]->GetSpawnPointOn() == true)
			{
				int r = rand()%ER+1;
				if(r == 1 && difficulty >= 5)
				{
					while(spawnTimer > 0)
					{
						spawnTimer -= 0.1f;
					}
					int tmpID[8];
					for(int j = 0; j < 8; ++j)
					{
						Animation* tmpAnimation = new Animation();
						tmpAnimation->LoadAnimationFromFile("SwarmAnimation.xml", j);
						tmpID[j] = AnimationSystem::GetInstance()->AddAnimation(tmpAnimation);
					}
					enemy = new SwarmBot();
					enemy->SetX(tileSet[i]->GetX());
					enemy->SetY(tileSet[i]->GetY());
					enemy->SetRoomNum(roomNumber);
					dynamic_cast<SwarmBot*>(enemy)->SetAnimation(tmpID);
					enemySet.push_back(enemy);
					if(enemyCount >= 1)
					{
						for(int j = 0; j < enemyCount; ++j)
						{
							if(enemySet[enemyCount]->GetX() == enemySet[j]->GetX())
								enemySet[enemyCount]->SetX(enemy->GetX()+64);
						}
					}
					spawnTimer = 25.0f;
					enemyCount += 1;
					difficulty -= 5;
				}
				/*else if(r == 2 && difficulty >= 10)
				{
					while(spawnTimer > 0)
					{
						spawnTimer -= 0.1f;
					}
					int tmpID[5];
					for(int j = 0; j < 5; ++j)
					{
						Animation* tmpAnimation = new Animation();
						tmpAnimation->LoadAnimationFromFile("TurretAnimation.xml", j);
						tmpID[j] = AnimationSystem::GetInstance()->AddAnimation(tmpAnimation);
					}
					enemy = new TurretBot();
					enemy->SetX(tileSet[i]->GetX());
					enemy->SetY(tileSet[i]->GetY());
					enemy->SetRoomNum(roomNumber);
					dynamic_cast<TurretBot*>(enemy)->SetAnimation(tmpID);
					enemySet.push_back(enemy);
					if(enemyCount >= 1)
					{
						for(int j = 0; j < enemyCount; ++j)
						{
							if(enemySet[enemyCount]->GetX() == enemySet[j]->GetX())
								enemySet[enemyCount]->SetX(enemySet[enemyCount]->GetX()+64);
						}
					}
					spawnTimer = 25.0f;
					enemyCount += 1;
					difficulty -= 5;
				}*/
				else if(r == 3 && difficulty >= 15)
				{
					while(spawnTimer > 0)
					{
						spawnTimer -= 0.1f;
					}
					int tmpID[8];
					for(int j = 0; j < 8; ++j)
					{
						Animation* tmpAnimation = new Animation();
						tmpAnimation->LoadAnimationFromFile("TankAnimation.xml", j);
						tmpID[j] = AnimationSystem::GetInstance()->AddAnimation(tmpAnimation);
					}
					enemy = new TankBot();
					enemy->SetX(tileSet[i]->GetX());
					enemy->SetY(tileSet[i]->GetY());
					enemy->SetRoomNum(roomNumber);
					dynamic_cast<TankBot*>(enemy)->SetAnimation(tmpID);
					enemySet.push_back(enemy);
					if(enemyCount >= 1)
					{
						for(int j = 0; j < enemyCount; ++j)
						{
							if(enemySet[enemyCount]->GetX() == enemySet[j]->GetX())
								enemySet[enemyCount]->SetX(enemySet[enemyCount]->GetX()+64);
						}
					}
					spawnTimer = 25.0f;
					enemyCount += 1;
					difficulty -= 15;
				}
				else if(r == 4 && difficulty >= 20)
				{
					while(spawnTimer > 0)
					{
						spawnTimer -= 0.1f;
					}
					enemy = new SapperBot();
					enemy->SetX(tileSet[i]->GetX());
					enemy->SetY(tileSet[i]->GetY());
					enemy->SetRoomNum(roomNumber);
					enemySet.push_back(enemy);
					if(enemyCount >= 1)
					{
						for(int j = 0; j < enemyCount; ++j)
						{
							if(enemySet[enemyCount]->GetX() == enemySet[j]->GetX())
								enemySet[enemyCount]->SetX(enemySet[enemyCount]->GetX()+64);
						}
					}
					spawnTimer = 25.0f;
					enemyCount += 1;
					difficulty -= 20;
				}
				else if(r == 5 && difficulty >= 20)
				{
					while(spawnTimer > 0)
					{
						spawnTimer -= 0.1f;
					}
					enemy = new RepairBot();
					enemy->SetX(tileSet[i]->GetX());
					enemy->SetY(tileSet[i]->GetY());
					enemy->SetRoomNum(roomNumber);
					dynamic_cast<RepairBot*>(enemy)->SetAnimationID(idH);
					dynamic_cast<RepairBot*>(enemy)->SetMoveSoundID(GamePlayState::GetInstance()->GetRepairBotSound());
					dynamic_cast<RepairBot*>(enemy)->SetHealSoundID(GamePlayState::GetInstance()->GetRepairSound());
					enemySet.push_back(enemy);
					if(enemyCount >= 1)
					{
						for(int j = 0; j < enemyCount; ++j)
						{
							if(enemySet[enemyCount]->GetX() == enemySet[j]->GetX())
								enemySet[enemyCount]->SetX(enemySet[enemyCount]->GetX()+64);
						}
					}
					spawnTimer = 20.0f;
					enemyCount += 1;
					difficulty -= 20;
				}
				else if(r == 6 && difficulty >= 25)
				{
					while(spawnTimer > 0)
					{
						spawnTimer -= 0.1f;
					}
					int tmpID[8];
					for(int j = 0; j < 8; ++j)
					{
						Animation* tmpAnimation = new Animation();
						tmpAnimation->LoadAnimationFromFile("StabAnimation.xml", j);
						tmpID[j] = AnimationSystem::GetInstance()->AddAnimation(tmpAnimation);
					}
					enemy = new BackstabBot();
					enemy->SetX(tileSet[i]->GetX());
					enemy->SetY(tileSet[i]->GetY());
					enemy->SetRoomNum(roomNumber);
					dynamic_cast<BackstabBot*>(enemy)->SetAnimation(tmpID);
					enemySet.push_back(enemy);
					if(enemyCount >= 1)
					{
						for(int j = 0; j < enemyCount; ++j)
						{
							if(enemySet[enemyCount]->GetX() == enemySet[j]->GetX())
								enemySet[enemyCount]->SetX(enemySet[enemyCount]->GetX()+64);
						}
					}
					spawnTimer = 25.0f;
					enemyCount += 1;
					difficulty -= 25;
				}
			}
			//if( enemy )
			//	enemy->AddRef();
		}
	}

	// Add enemies
	for(int i = 0; i < enemyCount; ++i)
	{
		ObjectManager::GetInstance()->AddObject(enemySet[i]);
	}
}

void Room::RemoveEnemy(Enemy* tmp)
{
	if(tmp == nullptr)
		return;

	tmp->Release();

	vector<Enemy*>::iterator iter;

	for(iter = enemySet.begin(); iter != enemySet.end(); ++iter)
	{
		if((*iter) == tmp)
		{
			iter = enemySet.erase(iter);
			break;
		}
	}
}